package Herramientas;

import CalendarioDAOS.CalendarioDAO;
import CalendarioDTOS.MesDTO;
import SistemaDTOS.UnidadMedidaDTO;
import java.io.File;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.RandomStringUtils;

/**
 *
 * @author Alan Gonzalez
 */
public class Herramientas {

    /**
     * ALAN GONZALEZ - METODO QUE VALIDA SI UNA PALABRA ES UN PALINDROMO Y
     * DEVUELVE UNA VARIABLE DE TIPO BOLEANO
     *
     * @param palabra
     * @return
     */
    public Boolean palindromoCheck(String palabra) {
        Boolean bo = new Boolean(null);
        String palabraReves = "";
        for (int x = palabra.length() - 1; x >= 0; x--) {
            palabraReves = palabraReves + palabra.charAt(x);
        }
        if (palabraReves.equals(palabra)) {
            bo = true;
        } else {
            bo = false;
        }
        return bo;
    }

    /**
     * ALAN GONZALEZ simple metodo para generar un vector con anios en cuenta
     * regresiva se usa para crear combos dinamicos y no estar editando el jsp
     *
     * @return
     */
    public Vector aniosCombo() {
        Vector anios = new Vector();
        Calendar fecha = new GregorianCalendar();
        int año = fecha.get(Calendar.YEAR);
        // cargando de años el vector del combi dinamico
        int aux = 0;
        for (aux = año; aux >= 1950; aux--) {
            anios.add(aux);
        }
        return anios;
    }

    /**
     * ALAN GONZALEZ Simple metodo para crear combos con meses
     *
     * @return
     */
    public Vector mesesCombo() {
        Vector m = new Vector();
        CalendarioDAO calendarioAPI = new CalendarioDAO();
        int aux = 1;
        int lim = 13;// uno a desface al indice
        for (aux = 1; aux < lim; aux++) {
            MesDTO mes = new MesDTO();
            mes.setNumeroMes(aux);
            mes.setNombreMes(calendarioAPI.nombreMes(aux));
            m.add(mes);
        }
        return m;
    }

    /**
     * ALAN GONZALEZ Simple Metodo para crear combos con dias
     *
     * @return
     */
    public Vector diasCombo() {
        Vector dias = new Vector();
        int aux = 1;
        for (aux = 1; aux <= 31; aux++) {
            int auxiliar = aux;
            dias.add(auxiliar);
        }
        System.out.println("DIAS EN EL VECTOR" + dias.size());
        return dias;
    }

    /**
     * Alan Gonzalez Metodo Para Encriptar cadena HASHING MD5
     *
     * @param cadenaOriginal
     * @return
     */
    public String encriptaMD5(String cadenaOriginal) {
        String cadenaEncriptada = new String();
        String md5 = null;
        try {
            //Create MessageDigest object for MD5
            MessageDigest digest = MessageDigest.getInstance("MD5");
            //Update input string in message digest
            digest.update(cadenaOriginal.getBytes(), 0, cadenaOriginal.length());
            //Converts message digest value in base 16 (hex) 
            md5 = new BigInteger(1, digest.digest()).toString(16);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return md5;
    }

    /**
     * ALAN GONZALEZ ESTE METODO SE UTILIZA PARA DESCOMPONER UNA CADENA EN UN
     * VECTOR QUE ALMACENA TODOS SUS CARACTERES
     *
     * @param cadena
     * @return
     */
    public Vector cadena_vector(String cadena) {
        Vector caracteres = new Vector();
        char[] car;
        car = cadena.toCharArray();
        int aux;
        for (aux = 0; aux < car.length; aux++) {
            caracteres.add(car[aux]);
        }
        return caracteres;
    }

    public String timeNow() {
        Calendar calendario = new GregorianCalendar();
        String time = new String();
        time = calendario.getTime().toString();
        return time;
    }

    /**
     * ALAN GONZALEZ METODO QUE DEVUELVE UNA CADENA ALFANUMERICA DE TAMAÑO
     * DETERMINADO EN EL PARAMETR HACE USO DE LIBRERIA APACHE COMONS LANG 3X
     *
     * @param tamaño
     * @return
     */
    public String cadenaAlfanumericaAleatoria(int tamaño) {
        String code = RandomStringUtils.randomAlphanumeric(tamaño);
        return code;
    }

    /**
     *
     * @param tamaño
     * @return
     */
    public String randomString(int tamaño) {
        String code = RandomStringUtils.randomAlphabetic(tamaño);
        return code;
    }

    /**
     * ALAN GONZALEZ METODO QUE DEVUELVE UN NUMERO ALEATORIO
     *
     * @param tamaño
     * @return
     */
    public int enteroAleatorio(int tamaño) {
        int aleatorio = 0;
        aleatorio = Integer.parseInt(RandomStringUtils.randomNumeric(tamaño));
        return aleatorio;
    }

    /**
     * ALAN GONZALEZ METODO DE DESCUENTO ENCADENADO TRIPLE AL ITEM
     *
     * @param cantidadOriginal
     * @param descuentoUno
     * @param descuentoDos
     * @param descuentoTres
     * @return
     */
    public double descuentoEncadenadoTriple(double cantidadOriginal, double descuentoUno, double descuentoDos, double descuentoTres) {
        double totalFinal = 0;
        double subTotalA = (cantidadOriginal) - ((cantidadOriginal * descuentoUno) / 100);
        double subTotalB = (subTotalA) - ((subTotalA * descuentoDos) / 100);
        double subTotalC = (subTotalB) - ((subTotalB * descuentoTres) / 100);
        totalFinal = subTotalC;
        return totalFinal;
    }

    /**
     * ALAN GONZALEZ METODO DESCUENTO ENCADENADO DOBLE AL ITEM
     *
     * @param cantidadOriginal
     * @param descuentoUno
     * @param descuentoDos
     * @return
     */
    public double descuentoEncadenadoDoble(double cantidadOriginal, double descuentoUno, double descuentoDos) {
        double totalFinal = 0;
        double subTotalA = (cantidadOriginal) - ((cantidadOriginal * descuentoUno) / 100);
        double subTotalB = (subTotalA) - ((subTotalA * descuentoDos) / 100);
        totalFinal = subTotalB;
        return totalFinal;
    }

    /**
     * ALAN GONZALEZ METODO DE DESCUENTO UNITARIO
     *
     * @param cantidad
     * @param descuento
     * @return
     */
    public double descuentoUnitario(double cantidad, double descuento) {
        double totalFinal = 0;
        totalFinal = (cantidad) - ((cantidad * descuento) / 100);
        return totalFinal;
    }

    /**
     * ALAN GONZALEZ
     *
     * @param cantidad
     * @param ieps
     * @return
     */
    public double totalItemIEPS(double cantidad, double ieps) {
        double total = (cantidad) + ((cantidad * ieps) / 100);
        return total;
    }

    /**
     * ALAN GONZALEZ SUMA LOS ITEMS DE UN VECTOR
     *
     * @return
     */
    public double sumaItemsVector(Vector<Double> vItems) {
        double total = 0;
        int aux = 0;
        double sub = 0.0;
        for (aux = 0; aux < vItems.size(); aux++) {
            sub = sub + vItems.elementAt(aux);
        }
        total = sub;
        return total;
    }

    /**
     * ALAN GONZALEZ | METODO QUE DEVUELVE UNA STRING FORMATEADA EXPRESANDO UN
     * NUMERO
     *
     * @param x
     * @return
     */
    public String redondeaDecimales(double x) {
        String nFormateado = new String();
        DecimalFormat df = new DecimalFormat("0.00");
        nFormateado = df.format(x);
        return nFormateado;
    }

    /**
     * ALAN GONAZALEZ UNIDADES DE MEDIDA
     *
     * @return
     */
    public Vector unidadesMedida() {
        Vector unidades = new Vector();
        PasarelaDatos db = new PasarelaDatos();
        db.openDatabase();
        String sql = "SELECT * FROM unidades_medida";
        ResultSet rst = db.executeQuery(sql);
        try {
            while (rst.next()) {
                UnidadMedidaDTO um = new UnidadMedidaDTO();
                um.setId(rst.getInt("id"));
                um.setAbreviatura(rst.getString("unidad"));
                um.setDescripcion(rst.getString("desc"));
                unidades.add(um);
            }
        } catch (SQLException ex) {
            Logger.getLogger(Herramientas.class.getName()).log(Level.SEVERE, null, ex);
        }
        db.closeDatabase();
        return unidades;
    }

    /**
     * ALAN GONZALEZ | ESTE METODO CALCULA EL IVA DE UN MONTO ORIGINAL Y LO
     * DEVUELVE EN UN TIPO DE DATO DOUBLE EJEMPLO IVA DE 100 LO QUE DEVUELVE
     * COMO RESULTADO SERIA 16 SEGUN EL PORCENTAJE EXPRESADO EN LA TABLA DE
     * IMPUESTOS
     *
     * @param montoSinIva
     * @return
     */
    public double calculoIva(double montoSinIva) {
        double iva = 0;
        double porcientoIva = 0;
        PasarelaDatos db = new PasarelaDatos();
        String sql = "select impuestos.iva from impuestos";
        db.openDatabase();
        ResultSet rst = db.executeQuery(sql);
        try {
            if (rst.next()) {
                porcientoIva = rst.getDouble("iva");
                iva = ((porcientoIva * montoSinIva) / 100);
            } else {
                porcientoIva = 0;
                System.out.println(" ####   ERROR NO SE ENCUENTRA CONFIGURACION DINAMICA DE IMPUESTOS VALIDA   ####");
            }
        } catch (SQLException ex) {
            Logger.getLogger(Herramientas.class.getName()).log(Level.SEVERE, null, ex);
        }
        db.closeDatabase();
        return iva;
    }

    /**
     * ALAN GONZALEZ | METODO PARA COMPROBAR SI UN ARCHIVO EXISTE
     *
     * @param ruta
     * @return
     */
    public boolean archivoExiste(String ruta) {
        boolean b = new Boolean(null);
        File fichero = new File(ruta);
        if (fichero.exists()) {
            b = true;
            System.out.println("El fichero " + ruta + " existe");
        } else {
            b = false;
            System.out.println("Pues va a ser que no");
        }
        return b;
    }

    /**
     * ALAN GONZALEZ VALIDADOR DE EMAIL
     *
     * @param email
     * @return
     */
    public boolean validarEmail(String email) {
        String PATTERN_EMAIL = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
        Pattern pattern = Pattern.compile(PATTERN_EMAIL);
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }

    /**
     * ALAN GONZALEZ ESTE METODO COMPARA DOS CADENAS Y DEVUELVE UN DATO DE TIPO
     * BOLEANO DEPENDIENDO DEL CASO
     *
     * @param CADENA_UNO
     * @param CADENA_DOS
     * @return
     */
    public boolean comparaDosCadenas(String CADENA_UNO, String CADENA_DOS) {
        boolean bandera = new Boolean(null);
        if (CADENA_UNO.equals(CADENA_DOS) && CADENA_DOS.equals(CADENA_UNO)) {
            bandera = true;
        } else {
            bandera = false;
        }
        return bandera;
    }

    /**
     * ALAN GONZALEZ
     *
     * @return
     */
    public String ipServidor() {
        String urlRed = new String();
        try {
            InetAddress direccion = InetAddress.getLocalHost();
            //String nombreDelHost = direccion.getHostName(); //nombre host
            String IP_local = direccion.getHostAddress();    //ip como String
            urlRed += "" + IP_local;
        } catch (UnknownHostException ex) {
            Logger.getLogger(Herramientas.class.getName()).log(Level.SEVERE, null, ex);
        }
        return urlRed;
    }

    /**
     * ALAN GONZALEZ RAZO HERRAMIENTA PARA EXTRAER LISTADO DE UNIDADES DE MEDIDA
     *
     * @param id
     * @return
     */
    public UnidadMedidaDTO unidadMedida(int id) {
        UnidadMedidaDTO unidad = new UnidadMedidaDTO();
        String sql = "SELECT * FROM unidades_medida WHERE unidades_medida.id = " + id;
        PasarelaDatos db = new PasarelaDatos();
        db.openDatabase();
        ResultSet rst = db.executeQuery(sql);
        try {
            if (rst.next()) {
                unidad.setId(rst.getInt("id"));
                unidad.setAbreviatura(rst.getString("unidad"));
                unidad.setDescripcion(rst.getString("desc"));
            } else {
                unidad = null;
                System.out.println("ERROR AL OBTENER UNIDADES DE MEDIDA");
            }
        } catch (SQLException ex) {
            Logger.getLogger(Herramientas.class.getName()).log(Level.SEVERE, null, ex);
        }
        return unidad;
    }

}
